use crate::utils::Point;

const THRESHOLD: u8 = 64;

pub struct CharacterCore {
    pub width: usize,
    pub matrix: Vec<Vec<u8>>,
}

impl CharacterCore {
    pub fn find_islands(&self) -> Vec<Vec<Point>> {
        let mut visited_matrix: Vec<Vec<bool>> = vec![vec![false; self.width]; self.width];

        let mut islands: Vec<Vec<Point>> = vec![];
        loop {
            match find_next_island(&mut visited_matrix, &self.matrix) {
                Some(p) => {
                    let (x, y) = p[0];
                    let mut island = Vec::new();
                    visited_matrix[y][x] = false;
                    extend_island(x, y, &mut island, &mut visited_matrix, &self.matrix);
                    islands.push(island);
                }
                None => {
                    break;
                }
            }
        }

        return islands;

        fn find_next_island(
            visited_matrix: &mut Vec<Vec<bool>>,
            matrix: &Vec<Vec<u8>>,
        ) -> Option<Vec<Point>> {
            for x in 0..visited_matrix.len() {
                for y in 0..visited_matrix[x].len() {
                    if visited_matrix[y][x] == false {
                        visited_matrix[y][x] = true;
                        if matrix[x][y] > THRESHOLD {
                            return Some(vec![(x, y)]);
                        }
                    }
                }
            }
            return None;
        }

        fn extend_island(
            x: usize,
            y: usize,
            island: &mut Vec<Point>,
            visited_matrix: &mut Vec<Vec<bool>>,
            matrix: &Vec<Vec<u8>>,
        ) {
            if x >= matrix.len() || y >= matrix[x].len() {
                return;
            }
            if visited_matrix[y][x] == true {
                return;
            }
            visited_matrix[y][x] = true;

            if matrix[x][y] > THRESHOLD {
                island.push((x, y));
                extend_island(x - 1, y, island, visited_matrix, matrix);
                extend_island(x + 1, y, island, visited_matrix, matrix);
                extend_island(x, y - 1, island, visited_matrix, matrix);
                extend_island(x, y + 1, island, visited_matrix, matrix)
            }
        }
    }
}
